package com.informatics.polymer.client.SubstructureSearch;

import org.restlet.gwt.Callback;
import org.restlet.gwt.Client;
import org.restlet.gwt.data.Form;
import org.restlet.gwt.data.MediaType;
import org.restlet.gwt.data.Method;
import org.restlet.gwt.data.Preference;
import org.restlet.gwt.data.Protocol;
import org.restlet.gwt.data.Request;
import org.restlet.gwt.data.Response;
import org.restlet.gwt.resource.Representation;

import com.google.gwt.user.client.Window;
import com.smartgwt.client.types.ListGridFieldType;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.types.SelectionAppearance;
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.types.Side;
import com.smartgwt.client.types.VisibilityMode;
import com.smartgwt.client.widgets.Button;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.HTMLFlow;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.layout.SectionStack;
import com.smartgwt.client.widgets.layout.SectionStackSection;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.tab.Tab;
import com.smartgwt.client.widgets.tab.TabSet;

/**
 * Class to represent a panel for substructure search.
 * 
 * @author ed
 * @version 1.0
 */
public class SubstructureSearchPanel extends SectionStack {
	/**
	 * String array to retain all ids found in the search.
	 */
	private String[] substructureMoleculeHits;

	/**
	 * Create SubstructureSearchPanel.
	 */
	public SubstructureSearchPanel() {
		setUpPanel();
	}

	/**
	 * Sets up the substructure search panel system.
	 */
	private void setUpPanel() {
		this.setVisibilityMode(VisibilityMode.MULTIPLE);
		this.setWidth(1000);
		this.setHeight(500);
		this.setBorder("2px solid #458B00");
		SectionStackSection section1 = new SectionStackSection(
				"Substructure Search");
		section1.setExpanded(true);
		HTMLFlow welcome = new HTMLFlow();
		welcome.setOverflow(Overflow.AUTO);
		welcome.setPadding(10);
		String welcomeString = "Welcome to the <I>\"Substructure Search\"</I> panel, please see the instructions tab "
				+ "below for more details on how to search for substructures.";
		welcome.setContents(welcomeString);
		section1.addItem(welcome);
		this.addSection(section1);
		this.setStyleName("sectionHeaderclosed");
		this.setBackgroundColor("#F0F0F0");
		// Search section.
		SectionStackSection searchSection = new SectionStackSection("Search");
		searchSection.addItem(jchemPaintPanel());
		// Need listgrid here with id, picture and property data.
		this.addSection(searchSection);
		// Search by IUPAC name
		SectionStackSection searchByIUPACName = new SectionStackSection(
				"Search by IUPAC Name");
		searchByIUPACName.addItem(searchByIupacNameTabSetUP());
		this.addSection(searchByIUPACName);
		// Add instructions section.
		SectionStackSection instructionSection = new SectionStackSection(
				"Instructions");
		instructionSection.setExpanded(false);
		HTMLFlow browseRepeatUnitInstructions = new HTMLFlow();
		browseRepeatUnitInstructions.setOverflow(Overflow.AUTO);
		browseRepeatUnitInstructions.setPadding(10);
		String instructions = "1. <b>Using the Search Panel.</b><br></br> Use the search tab to draw a chemical structure to search for repeat units that contain that structure.<br></br>"
				+ "Simply draw the structure into the editor and press the search button, the hits will be displayed in a grid below.<br></br>"
				+ "2.<b>Delete Panel</b><br></br> If you are not happy with your selection or choose to view another panel you can click on the <I>\"Delete Panel\"</I> and press the delete panel button"
				+ " this will delete the browse repository panel, so you can start over again.<br></br>";
		browseRepeatUnitInstructions.setContents(instructions);
		instructionSection.addItem(browseRepeatUnitInstructions);
		this.addSection(instructionSection);
		// Delete panel section
		SectionStackSection deletePanelSection = new SectionStackSection(
				"Delete Panel");
		deletePanelSection.setExpanded(false);
		Button deletePanelButton = new Button("Delete Panel!");
		deletePanelButton.setSize("100", "30");
		deletePanelButton.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				destroy();
			}
		});
		deletePanelSection.addItem(deletePanelButton);
		this.addSection(deletePanelSection);
	}

	/**
	 * TabSet panel for JChempaint
	 * 
	 * @return TabSet - tabs containing jchemPaint applets.
	 */
	private TabSet jchemPaintPanel() {
		TabSet drawingPanels = new TabSet();
		drawingPanels.setBackgroundColor("#F0F0F0");
		drawingPanels.setTabBarPosition(Side.TOP);
		drawingPanels.setWidth(1000);
		drawingPanels.setHeight(500);
		// Add separate panes.
		Tab tTab1 = new Tab("Draw Repeat Unit");
		Canvas tab1Canvas = new Canvas();
		tab1Canvas.setBackgroundColor("#F0F0F0");
		String appletCode = "<br></br>  <applet code=\"org.openscience.cdk.applications.jchempaint.applet.JChemPaintEditorApplet\" archive=\"jchempaint-applet-core.jar\" name=\"appletSS\" width=\"450\" height=\"375\">"
				+ "</applet>";
		tab1Canvas.setContents(appletCode);
		Tab tTab2 = new Tab("Search Results");
		final Canvas tab2Canvas = new Canvas();
		tab2Canvas.setBackgroundColor("#F0F0F0");
		Button searchDatabaseButton = new Button("Search");
		searchDatabaseButton.setSize("300", "30");
		searchDatabaseButton.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				int numberofRGroups = countNumberofFragmentPoints(
						callGetData(), "[Pr]");
				if (numberofRGroups == 0 && callGetData() != "") {
					String smileStringToAdd = callGetData();// .replace("[Pr]",
					// "[*]");
					Window.alert(smileStringToAdd);
					ListGrid substructureSearchResults = new ListGrid();
					substructureSearchResults
							.setSelectionType(SelectionStyle.SIMPLE);
					substructureSearchResults
							.setSelectionAppearance(SelectionAppearance.CHECKBOX);
					substructureSearchResults.setPixelSize(500, 300);
					ListGridField idValue = new ListGridField("PolymerID",
							"ID", 100);
					ListGridField structure = new ListGridField(
							"chemicalStructure", "Structure", 400);
					structure.setType(ListGridFieldType.IMAGE);
					structure.setImageHeight(200);
					structure.setImageWidth(400);
					substructureSearchResults.setFields(idValue, structure);
					substructureSearchResults.setShowAllRecords(true);
					// Actual call
					Request request = new Request(Method.GET,
							"http://localhost:8080/svc/substructuresearch/"
									+ callGetData());
					request.getClientInfo().getAcceptedMediaTypes().add(
							new Preference<MediaType>(MediaType.TEXT_PLAIN));
					new Client(Protocol.HTTP).handle(request, new Callback() {
						@Override
						public void onEvent(Request request, Response response) {
							substructureMoleculeHits = response.getEntity()
									.getText().split("\n");
						}
					});
					// add the datasource to the listgrid
					SubstructureSearchDataRecord[] vals = new SubstructureSearchDataRecord[substructureMoleculeHits.length];
					int countofRecords = 0;
					for (String s : substructureMoleculeHits) {
						SubstructureSearchDataRecord ssdr1 = new SubstructureSearchDataRecord(
								s, "http://localhost:8080/RepeatUnitPictures/"
										+ s.trim() + ".png");
						ssdr1.setAttribute("PolymerID", ssdr1.getID());
						ssdr1.setAttribute("chemicalStructure", ssdr1.getImg());
						vals[countofRecords] = ssdr1;
						countofRecords++;
					}
					substructureSearchResults.setData(vals);
					tab2Canvas.addChild(substructureSearchResults);
				}
			}
		});
		// Restlet code to add repeat unit goest here
		tTab1.setPane(tab1Canvas);
		drawingPanels.addTab(tTab1);
		tab1Canvas.addChild(searchDatabaseButton);
		tTab2.setPane(tab2Canvas);
		drawingPanels.addTab(tTab2);
		return drawingPanels;
	}

	/**
	 * Native javascript method to invoke the DOM and extract smile strings from
	 * JchemPaint
	 * 
	 * @return String representation of the repeat unit.
	 */
	private native String callGetData() /*-{
		var smileString;
		smileString = $doc.appletSS.getSmiles();
		return smileString;
	}-*/;

	/**
	 * This method checks the number of R atoms drawn for the repeat units and
	 * end groups in JChempaint.
	 * 
	 * @param text
	 *            - R group value [R].
	 * @param search
	 *            - Smile string to search.
	 * @return - int value representing the number of R groups in a molecule.
	 */
	private int countNumberofFragmentPoints(final String text,
			final String search) {
		int count = 0;
		for (int fromIndex = 0; fromIndex > -1; count++) {
			fromIndex = text.indexOf(search, fromIndex + ((count > 0) ? 1 : 0));
		}
		return count - 1;
	}

	private TabSet searchByIupacNameTabSetUP() {
		TabSet tabPanels = new TabSet();
		tabPanels.setBackgroundColor("#F0F0F0");
		tabPanels.setTabBarPosition(Side.TOP);
		tabPanels.setWidth(1000);
		tabPanels.setHeight(500);
		Tab tTab1 = new Tab("IUPAC Query");
		Canvas tab1Canvas = new Canvas();
		tab1Canvas.setBackgroundColor("#F0F0F0");
		final DynamicForm form = new DynamicForm();
		form.setWidth(250);
		VLayout opsinLayout = new VLayout();
		final TextItem usernameItem = new TextItem();
		usernameItem.setTitle("IUPAC Name");
		usernameItem.setRequired(true);
		form.setFields(usernameItem);
		Button submitName = new Button("Submit");
		tab1Canvas.addChild(form);
		Tab tTab2 = new Tab("Search Results");
		final Canvas tab2Canvas = new Canvas();
		tab2Canvas.setBackgroundColor("#F0F0F0");
		submitName.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				ListGrid substructureSearchResults = new ListGrid();
				substructureSearchResults
						.setSelectionType(SelectionStyle.SIMPLE);
				substructureSearchResults
						.setSelectionAppearance(SelectionAppearance.CHECKBOX);
				substructureSearchResults.setPixelSize(500, 300);
				ListGridField idValue = new ListGridField("PolymerID", "ID",
						100);
				ListGridField structure = new ListGridField(
						"chemicalStructure", "Structure", 400);
				structure.setType(ListGridFieldType.IMAGE);
				structure.setImageHeight(200);
				structure.setImageWidth(400);
				substructureSearchResults.setFields(idValue, structure);
				substructureSearchResults.setShowAllRecords(true);
				Window.alert(usernameItem.getDisplayValue());
				// Actual call
				final Client client = new Client(Protocol.HTTP);
				Form form = new Form();
				form.add("IUPACName", usernameItem.getDisplayValue());
				Representation rep = form.getWebRepresentation();
				client.post("http://localhost:8080/svc/opsinsubstructuresearch", rep, new Callback() {
				@Override
				public void onEvent(Request request, Response response) {
					substructureMoleculeHits = response.getEntity()
								.getText().split("\n");
						Window.alert(response.getEntity().getText());
					}
				});
				// add the datasource to the listgrid
				SubstructureSearchDataRecord[] vals = new SubstructureSearchDataRecord[substructureMoleculeHits.length];
				int countofRecords = 0;
				for (String s : substructureMoleculeHits) {
					SubstructureSearchDataRecord ssdr1 = new SubstructureSearchDataRecord(
							s, "http://localhost:8080/RepeatUnitPictures/"
									+ s.trim() + ".png");
					ssdr1.setAttribute("PolymerID", ssdr1.getID());
					ssdr1.setAttribute("chemicalStructure", ssdr1.getImg());
					vals[countofRecords] = ssdr1;
					countofRecords++;
				}
				substructureSearchResults.setData(vals);
				tab2Canvas.addChild(substructureSearchResults);

			}
		});
		opsinLayout.addMember(form);
		opsinLayout.addMember(submitName);
		tab1Canvas.addChild(opsinLayout);
		tTab1.setPane(tab1Canvas);
		tabPanels.addTab(tTab1);
		tTab2.setPane(tab2Canvas);
		tabPanels.addTab(tTab2);
		return tabPanels;
	}

}
